﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LIMS.Entities;
using LIMS.DataAccess;
using System.Collections;
using System.Reflection;
using Castle.Core.Logging;
using System.Net.Mail;
using System.Net;
using System.Xml;
using System.IO;

namespace LIMS.Service
{
    public class MailService : IMailService
    {
        //Private DBA interfaces, in case it needs database later on..
        //private IDaoFactory oDBFactory;
        private ILogger logger;
        private string SenderEmailAddress;
        private string Password;
        private int Port;
        private string HostName;
        private bool bSSL;
        //Constructor
        public MailService(ILogger oLogger)
        {
            this.logger = oLogger;
            if (!LoadConfigFileSettings())
                throw new Exception("Mail settings file could not be read");
        }

        /// <summary>
        /// Creates Email body based on template.
        /// </summary>
        /// <param name="oType"></param>
        /// <param name="sParams"></param>
        public bool CreateEmailBody(ref string sEmailBody,ref string sSubject,EmailType oType, params string[] sParams)
        {
            string sTemplatePath = string.Empty;
            try
            {
                switch (oType)
                {
                    //Email password reset
                    case EmailType.ResetPassword:
                        sTemplatePath = Resource.MAIL_PASSWORD_RESET_TEMPLATE;
                        break;
                    case EmailType.UserRegistrationToAdmin:
                        sTemplatePath = Resource.MAIL_USER_REGISTRATION_TO_ADMIN_TEMPLATE;
                        break;
                    case EmailType.UserRegistrationToUser:
                        sTemplatePath = Resource.MAIL_USER_REGISTRATION_TO_USER_TEMPLATE;
                        break;

                    case EmailType.CustomerHaveLessCreditLimit:
                        sTemplatePath = Resource.MAIL_CUSTOMER_LESS_CREDIT_TEMPLATE;
                        break;
                    case EmailType.ThanksForOrder:
                        sTemplatePath = Resource.MAIL_THANKS_FOR_ORDER;
                        break;
                    case EmailType.OrderUnderProcess:
                        sTemplatePath = Resource.MAIL_ORDER_UNDER_PROCESS;
                        break;
                    case EmailType.GoodsDispatched:
                        sTemplatePath = Resource.MAIL_GOODS_DISPATCHED;
                        break;
                    case EmailType.OrderCancelled:
                        sTemplatePath = Resource.MAIL_ORDER_CANCELLED;
                        break;
                    case EmailType.OrderDelivered:
                        sTemplatePath = Resource.MAIL_ORDER_DELIVERED;
                        break;
                    case EmailType.CustomerRegistration:
                        sTemplatePath = Resource.MAIL_CUSTOMER_REGISTRATION;
                        break;
                    case EmailType.OverDueInvoice:
                        sTemplatePath = Resource.MAIL_OVERDUE_INVOICE;
                        break;
                        

                }
                sTemplatePath = AppDomain.CurrentDomain.BaseDirectory + sTemplatePath;
                if (File.Exists(sTemplatePath))
                {
                    StreamReader oStream = new StreamReader(sTemplatePath);
                    sSubject = oStream.ReadLine();
                    sEmailBody = oStream.ReadToEnd();
                    oStream = null;
                    sEmailBody = sEmailBody.Replace(sSubject,string.Empty);
                    sSubject = sSubject.Replace("<Subject>", string.Empty);
                    sSubject = sSubject.Replace("</Subject>", string.Empty);
                    sSubject = ReplaceEmailTags(sSubject, sParams);
                    sEmailBody = ReplaceEmailTags(sEmailBody, sParams);
                    return true;
                }
                else
                {
                    logger.Error("Template file does not exist at : " + sTemplatePath);
                    return false;
                }
                
            }
            catch (Exception ex)
            {
                logger.Error("Error while creating CreateEmailBody", ex);
                return false;
            }
        }

        /// <summary>
        /// Replace Email Tags { }
        /// </summary>
        /// <param name="sEmailBody"></param>
        /// <param name="sParameters"></param>
        /// <returns></returns>
        private string ReplaceEmailTags(string sEmailBody, params string[] sParameters)
        {
            int iIndex = 1;
            for (var i = 0; i < sParameters.Length; i++)
            {
                sEmailBody = sEmailBody.Replace("{" + iIndex + "}", sParameters[i]);
                iIndex++;
            }
            return sEmailBody;
        }


        /// <summary>
        /// Sends Email
        /// </summary>
        /// <param name="sTo"></param>
        /// <param name="sFrom"></param>
        /// <param name="sSubject"></param>
        /// <param name="sBody"></param>
        /// <returns></returns>
        public bool SendEmail(List<string> sTo, string sFrom, string sSubject, string sBody)
        {
            SmtpClient oSMTPClient = new SmtpClient();
            MailMessage oMailMessage = new MailMessage();
            NetworkCredential oNetworkCredentials = new NetworkCredential(SenderEmailAddress, Password);
            try
            {
                /// Configure SMTP server.
                oSMTPClient.Host = HostName;
                oSMTPClient.Port = Port;

                //oSMTPClient.UseDefaultCredentials = true;
                oSMTPClient.Credentials = oNetworkCredentials;
                oSMTPClient.EnableSsl = bSSL;
                /// Assign TO address fields.
                foreach (string sRecipient in sTo)
                {
                    if (sRecipient != null)
                    {
                        MailAddress oTo = new MailAddress(sRecipient);
                        oMailMessage.To.Add(oTo);
                    }
                }
                /// Assisgn from address field.
                if (string.IsNullOrEmpty(sFrom))
                {
                    sFrom = SenderEmailAddress;
                }
                MailAddress oFrom = new MailAddress(sFrom);
                /// Set mail attributes.
                oMailMessage.Subject = sSubject;

                oMailMessage.From = oFrom;
                oMailMessage.IsBodyHtml = true;
                oMailMessage.Body = sBody;
                /// Send Email.
                oSMTPClient.Send(oMailMessage);
                return true;
            }
            catch (Exception ex)
            {
                logger.Error("Error while sending e-mail.", ex);
                return false;
            }
        }

        /// <summary>
        /// Loads configuration file
        /// </summary>
        /// <returns></returns>
        private bool LoadConfigFileSettings()
        {
            XmlDocument oXMLSettings = new XmlDocument();
            XmlElement oRootElement;
            try
            {
                oXMLSettings.Load(System.AppDomain.CurrentDomain.BaseDirectory + Resource.MAIL_CONFIG_FILE);
                logger.Info("Mail configuration file loaded successfully.");
                oRootElement = oXMLSettings.DocumentElement;
                SenderEmailAddress = oRootElement.SelectSingleNode("SenderEmailAddress").InnerText;
                Password = oRootElement.SelectSingleNode("Password").InnerText;
                HostName = oRootElement.SelectSingleNode("HostName").InnerText;
                Port = int.Parse(oRootElement.SelectSingleNode("Port").InnerText);
                bSSL = oRootElement.SelectSingleNode("SSL").InnerText.ToUpper().Equals("TRUE") ? true : false;
                return true;
            }
            catch (Exception ex)
            {
                logger.Error("Error while reading mail configuration file", ex);
                return false;
            }
        }
    }
}
